/* Microsoft Reference Implementation for TPM 2.0
 *
 *  The copyright in this software is being made available under the BSD License,
 *  included below. This software may be subject to other third party and
 *  contributor rights, including patent rights, and no such rights are granted
 *  under this license.
 *
 *  Copyright (c) Microsoft Corporation
 *
 *  All rights reserved.
 *
 *  BSD License
 *
 *  Redistribution and use in source and binary forms, with or without modification,
 *  are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice, this list
 *  of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright notice, this
 *  list of conditions and the following disclaimer in the documentation and/or
 *  other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "Tpm.h"
#include "PolicyPassword_fp.h"

#if CC_PolicyPassword  // Conditional expansion of this file

#include "Policy_spt_fp.h"

/*(See part 3 specification)
// allows a policy to be bound to the authorization value of the authorized
// object
*/
/*
TPM2_PolicyPassword与 TPM2_PolicyAuthvalue 的区别在于，password 直接比较授权值， authvalue 是比较 hmac

tpm2_policypassword(1) - Enables a policy that requires the object's authentication passphrase be provided. This is equivalent 
to authenticating using the object passphrase in plaintext, only this enforces it as a policy. It provides a mechanism to allow for 
password authentication when an object only allows policy based authorization, ie object attribute "userwithauth" is 0.
Tpm2_poliypassword (1)-启用需要提供对象身份验证密码短语的策略。这相当于在明文中使用对象密码短语进行身份验证，只不过这是将其作为策略强制执行的。
它提供了一种机制，允许在对象只允许基于策略的授权时进行密码身份验证，即对象属性“ userwithauth”为0。

This command allows a policy to be bound to the authorization value of the authorized object.
When this command completes successfully, policySession→isPasswordNeeded is SET to indicate that authValue of the authorized object 
will be checked when the session is used for authorization. The caller will provide the authValue in clear text in the hmac parameter 
of the authorization. The comparison of hmac to authValue is performed as if the authorization is a password.
NOTE 1 The parameter field in the policy session where the authorization value is provided is called hmac. If TPM2_PolicyPassword() is 
part of the sequence, then the field will contain a password and not an HMAC
此命令允许将策略绑定到授权对象的授权值。
当此命令成功完成时，policySession→isPasswordNeeded 被设置，表明在会话用于授权时将检查授权对象的authValue。 调用者将在授权的 hmac 
参数中以明文形式提供 authValue。 hmac 与 authValue 的比较就像授权是密码一样执行。
注 1 提供授权值的策略会话中的参数字段称为 hmac。 如果 TPM2_PolicyPassword() 是序列的一部分，则该字段将包含密码而不是 HMAC

*/
TPM_RC
TPM2_PolicyPassword(
    PolicyPassword_In   *in             // IN: input parameter list
    )
{
    SESSION             *session;
    TPM_CC               commandCode = TPM_CC_PolicyAuthValue;
    HASH_STATE           hashState;

// Internal Data Update

    // Get pointer to the session structure
    session = SessionGet(in->policySession);

    // Update policy hash
    // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyAuthValue)
    //  Start hash
    CryptHashStart(&hashState, session->authHashAlg);

    //  add old digest
    CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);

    //  add commandCode
    CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);

    //  complete the digest
    CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);

    //  Update isPasswordNeeded bit
    session->attributes.isPasswordNeeded = SET;
    session->attributes.isAuthValueNeeded = CLEAR;

    return TPM_RC_SUCCESS;
}

#endif // CC_PolicyPassword